package com.gzhryc.shared_device.oem.micro.api.controllers.xcx.v1.pcl;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alipay.api.response.AlipayTradeCreateResponse;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.pay.adaptation.alipay.AlipayNormalPayService;
import com.gzhryc.pay.adaptation.weixin.WXPayNormalPayService;
import com.gzhryc.pay.adaptation.weixin.msg.normal.WXPayNormalPayResponse;
import com.gzhryc.servlet.WebUtils;
import com.gzhryc.servlet.annotation.Route;
import com.gzhryc.shared_device.base.enums.EOperatorType;
import com.gzhryc.shared_device.base.enums.EPayState;
import com.gzhryc.shared_device.base.enums.EPayType;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.common.device.dao.db.Device;
import com.gzhryc.shared_device.common.device.services.DeviceService;
import com.gzhryc.shared_device.common.payment.dao.db.AlipayOrder;
import com.gzhryc.shared_device.common.payment.dao.db.WXPayOrder;
import com.gzhryc.shared_device.common.payment.services.AlipayOrderService;
import com.gzhryc.shared_device.common.payment.services.WXPayOrderService;
import com.gzhryc.shared_device.oem.code.PayServiceFactory;
import com.gzhryc.shared_device.oem.code.business.EBusinessType;
import com.gzhryc.shared_device.oem.code.config.dao.enums.EAgreementCode;
import com.gzhryc.shared_device.oem.code.member.LoginMember;
import com.gzhryc.shared_device.oem.code.member.services.MemberAgreementService;
import com.gzhryc.shared_device.oem.code.order.CacheOrderCollect;
import com.gzhryc.shared_device.oem.micro.api.MicroConstants;
import com.gzhryc.shared_device.oem.micro.api.OrderCollectManager;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.ClientAPICodeConstants;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.PayResultCode;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.pcl.PCLChangePwdRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.pcl.PCLChangePwdResponse;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.pcl.PCLLeasePayRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.pcl.PCLLeasePayResponse;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.pcl.PCLPayResultRequest;
import com.gzhryc.shared_device.oem.micro.api.dto.xcx.v1.pcl.PCLPayResultResponse;
import com.gzhryc.shared_device.pcl.code.dao.db.ChargingCable;
import com.gzhryc.shared_device.pcl.code.dao.db.PCLFeeTemplate;
import com.gzhryc.shared_device.pcl.code.dao.db.PCLOrder;
import com.gzhryc.shared_device.pcl.code.dao.enums.PCLOrderEnum;
import com.gzhryc.shared_device.pcl.code.dao.models.SetMealContent;
import com.gzhryc.shared_device.pcl.code.services.ChargingCableService;
import com.gzhryc.shared_device.pcl.code.services.PCLFeeTemplateService;
import com.gzhryc.shared_device.pcl.code.services.PCLOrderService;

public class PCLPayController {

    static Logger log = Logger.getLogger(PCLPayController.class);

    @Route(value = {"/xcx/v1/pcl/lease/pay.do"}, method = "POST")
    public PCLLeasePayResponse leasePay(HttpServletRequest request, HttpServletResponse response) {
        PCLLeasePayResponse apiResp = new PCLLeasePayResponse(ClientAPICodeConstants.EXECUTE_ERROR, "支付失败，请稍后再试");
        try {
            PCLLeasePayRequest apiReq = WebUtils.getJsonRequest(request, PCLLeasePayRequest.class);
            if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getDeviceSn()) && apiReq.getBody().getTemplateId() != null
                && apiReq.getBody().getSetMealId() != null) {
                String deviceSn = apiReq.getBody().getDeviceSn().trim();
                Integer payType = apiReq.getBody().getPayType() == null ? EPayType.WXPay.index() : apiReq.getBody().getPayType();

                if (EPayType.WXPay.index().equals(payType) || EPayType.Alipay.index().equals(payType)) {
                    if (StringTools.isBlank(apiReq.getBody().getAppId())) {
                        apiResp.setMsg("无效的应用ID");
                        return apiResp;
                    }
                }
                
                LoginMember loginMember = WebUtils.getAttribute(request, MicroConstants.ATTR_LOGIN_MEMBER, LoginMember.class);

                Device device = DeviceService.self().getByDeviceSn(deviceSn);
                if (device == null || device.getPlaceId() == null) {
                    apiResp.setMsg("设备未部署");
                    return apiResp;
                }

                ChargingCable chargingCable = ChargingCableService.self().getByDeviceSn(deviceSn);
                if (chargingCable == null) {
                    log.error("未找到{{0}}设备",deviceSn);
                    return apiResp;
                }
                
                //同意协议
                if (StringTools.isNotBlank(apiReq.getBody().getAppId())) {
                	MemberAgreementService.self().signing(loginMember.getId(), EAgreementCode.RentAgreement.name(), apiReq.getBody().getAppId());
                }

                SetMealContent.Item setMealItem = null;

                PCLFeeTemplate feeTemplate = PCLFeeTemplateService.self().getById(apiReq.getBody().getTemplateId());
                if(feeTemplate != null && StringTools.isNotBlank(feeTemplate.getSetMealContent())){
                    SetMealContent setMealContent = JsonTools.fromJson(feeTemplate.getSetMealContent(),SetMealContent.class);
                    if(setMealContent != null && setMealContent.getItems().size() > 0){
                        for(SetMealContent.Item item : setMealContent.getItems()){
                            if(item.getId().equals(apiReq.getBody().getSetMealId())){
                                setMealItem = item;
                                break;
                            }
                        }
                    }
                }

                if(setMealItem == null){
                    apiResp.setMsg("未找到套餐信息");
                    return apiResp;
                }

                if (EPayType.WXPay.index().equals(payType)) {
                    WXPayNormalPayService payService = PayServiceFactory.self().getWXPayNormalPayService(apiReq.getBody().getAppId(),
                            EBusinessType.PCL.index());
                    if (payService == null) {
                        apiResp.setMsg("未配置应用支付服务");
                        return apiResp;
                    }

                    OperateInfo operateInfo = new OperateInfo(MicroConstants.PROGRAM_TYPE, MicroConstants.PROGRAM_TYPE_NAME);
                    operateInfo.setOperator(EOperatorType.Member.index(), loginMember.getFullName());
                    operateInfo.setOperateNote("租借便捷线充");

                    CacheOrderCollect orderCollect = OrderCollectManager.buildPCLCacheOrderCollect(loginMember, device, chargingCable,
                            feeTemplate, setMealItem,payService.getConfig(), operateInfo);
                    if (orderCollect == null) {
                        apiResp.setMsg("创建订单失败，请稍后再试");
                        return apiResp;
                    }

                    WXPayNormalPayResponse externalResult = payService.applyPayOrder(orderCollect.getPayOrder());
                    if (externalResult != null) {
                        if(StringTools.isNotBlank(externalResult.getPrepay_id())) {
                            String payInfo = payService.buildXCXData(externalResult.getPrepay_id());
                            if (StringTools.isNotBlank(payInfo)) {
                                OrderCollectManager.saveWXPayOrderExternalContent(orderCollect.getPayOrder().getTradeNo(), JsonTools.toJson(externalResult));
                                log.info("微信支付返回：" + payInfo);
                                apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                                apiResp.getBody().setTradeNo(orderCollect.getPayOrder().getTradeNo());
                                apiResp.getBody().setPayType(payType);
                                apiResp.getBody().setPayInfo(payInfo);
                            }
                        }else {
                            log.error("微信支付返回错误，返回信息：{{0:json}}", externalResult);
                        }
                    } else {
                        log.error("微信支付无返回，订单信息：{{0:json}}", orderCollect);
                    }
                }else if (EPayType.Alipay.index().equals(payType)) {
                	AlipayNormalPayService payService = PayServiceFactory.self().getAlipayNormalPayService(apiReq.getBody().getAppId(),
                            EBusinessType.PCL.index());
                    if (payService == null) {
                        apiResp.setMsg("未配置应用支付服务");
                        return apiResp;
                    }
                    
                    OperateInfo operateInfo = new OperateInfo(MicroConstants.PROGRAM_TYPE, MicroConstants.PROGRAM_TYPE_NAME);
                    operateInfo.setOperator(EOperatorType.Member.index(), loginMember.getFullName());
                    operateInfo.setOperateNote("租借便捷线充");

                    CacheOrderCollect orderCollect = OrderCollectManager.buildPCLCacheOrderCollect(loginMember, device, chargingCable,
                            feeTemplate, setMealItem,payService.getConfig(), operateInfo);
                    if (orderCollect == null) {
                        apiResp.setMsg("创建订单失败，请稍后再试");
                        return apiResp;
                    }
                    
                    AlipayTradeCreateResponse externalResult = payService.applyPayOrder(orderCollect.getAlipayOrder());
                    if (externalResult != null) {
                        if(StringTools.isNotBlank(externalResult.getOutTradeNo())) {
                        	OrderCollectManager.saveAlipayOrderExternalContent(orderCollect.getAlipayOrder().getTradeNo(), JsonTools.toJson(externalResult));
                            apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                            apiResp.getBody().setTradeNo(externalResult.getTradeNo());
                            apiResp.getBody().setPayType(payType);
                        }else {
                            log.error("支付宝支付返回错误，返回信息：{{0:json}}", externalResult);
                        }
                    } else {
                        log.error("支付宝支付无返回，订单信息：{{0:json}}", orderCollect);
                    }
                }else {
                	 apiResp.setMsg("无效的支付类型");
                     return apiResp;
                }
            }
        } catch (Exception e) {
            log.error("创建订单失败，" + e.getMessage(), e);
        }
        return apiResp;
    }

    @Route(value = {"/xcx/v1/pcl/pay/result.do"}, method = "POST")
    public PCLPayResultResponse payResult(HttpServletRequest request){
        PCLPayResultResponse apiResp = new PCLPayResultResponse(ClientAPICodeConstants.NULL_DATA, "未找到支付结果");
        try {
            PCLPayResultRequest apiReq = WebUtils.getJsonRequest(request, PCLPayResultRequest.class);
            if (apiReq != null && apiReq.getBody().getPayType() != null && StringTools.isNotBlank(apiReq.getBody().getTradeNo())) {
                if(EPayType.WXPay.index().equals(apiReq.getBody().getPayType())){
                    //从缓存获取，如果存在则代表未支付
                    CacheOrderCollect cacheOrderCollect = OrderCollectManager.getCacheOrderCollect(apiReq.getBody().getTradeNo());
                    if(cacheOrderCollect != null){
                        return apiResp;
                    }

                    Date createDate = new Date();
                    WXPayOrder payOrder = WXPayOrderService.self(createDate).getByTradeNo(apiReq.getBody().getTradeNo());
                    if (payOrder != null) {
                        apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                        apiResp.getBody().setResultCode(PayResultCode.WAIT);
                        if (EPayState.Success.index().equals(payOrder.getPayStatus())) {
                            PCLOrder deviceOrder = PCLOrderService.self(new Date()).getByTradeNo(payOrder.getBusinessTradeNo());
                            if (deviceOrder != null) {
                                if (PCLOrderEnum.State.Working.index().equals(deviceOrder.getState())) {
                                    apiResp.getBody().setResultCode(PayResultCode.SUCCESS);
                                    apiResp.getBody().setPwdStr(deviceOrder.getPwd());
                                }
                            } else {
                                log.error("未找到设备订单，支付订单号：{{0}}，业务订单号：{{1}}", payOrder.getTradeNo(), payOrder.getBusinessTradeNo());
                            }
                        }
                    }
                }else if(EPayType.Alipay.index().equals(apiReq.getBody().getPayType())){
                    //从缓存获取，如果存在则代表未支付
                    CacheOrderCollect cacheOrderCollect = OrderCollectManager.getCacheOrderCollect(apiReq.getBody().getTradeNo());
                    if(cacheOrderCollect != null){
                        return apiResp;
                    }

                    Date createDate = new Date();
                    AlipayOrder payOrder = AlipayOrderService.self(createDate).getByTradeNo(apiReq.getBody().getTradeNo());
                    if (payOrder != null) {
                        apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                        apiResp.getBody().setResultCode(PayResultCode.WAIT);
                        if (EPayState.Success.index().equals(payOrder.getPayStatus())) {
                            PCLOrder deviceOrder = PCLOrderService.self(new Date()).getByTradeNo(payOrder.getBusinessTradeNo());
                            if (deviceOrder != null) {
                                if (PCLOrderEnum.State.Working.index().equals(deviceOrder.getState())) {
                                    apiResp.getBody().setResultCode(PayResultCode.SUCCESS);
                                    apiResp.getBody().setPwdStr(deviceOrder.getPwd());
                                }
                            } else {
                                log.error("未找到设备订单，支付订单号：{{0}}，业务订单号：{{1}}", payOrder.getTradeNo(), payOrder.getBusinessTradeNo());
                            }
                        }
                    }
                }else if(EPayType.EWallet.index().equals(apiReq.getBody().getPayType())){
                    PCLOrder deviceOrder = PCLOrderService.self(new Date()).getByTradeNo(apiReq.getBody().getTradeNo());
                    if (deviceOrder != null) {
                        apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                        apiResp.getBody().setResultCode(PayResultCode.WAIT);
                        if (PCLOrderEnum.State.Working.index().equals(deviceOrder.getState())) {
                            apiResp.getBody().setResultCode(PayResultCode.SUCCESS);
                            apiResp.getBody().setPwdStr(deviceOrder.getPwd());
                        }
                    } else {
                        log.error("未找到设备订单，支付类型：{{0}}，业务订单号：{{1}}", EPayType.EWallet.note(), apiReq.getBody().getTradeNo());
                    }
                }else {
	               	 apiResp.setMsg("无效的支付类型");
	                 return apiResp;
	            }
            }
        } catch (Exception e) {
            log.error("获取订单结果失败，" + e.getMessage(), e);
        }
        return apiResp;
    }

    @Route(value = {"/xcx/v1/pcl/pwd/change.do"}, method = "POST")
    public PCLChangePwdResponse changePwd(HttpServletRequest request){
        PCLChangePwdResponse apiResp = new PCLChangePwdResponse(ClientAPICodeConstants.EXECUTE_ERROR, "操作失败");
        try {
            LoginMember loginMember = WebUtils.getAttribute(request, MicroConstants.ATTR_LOGIN_MEMBER, LoginMember.class);
            if(loginMember != null) {
                PCLChangePwdRequest apiReq = WebUtils.getJsonRequest(request, PCLChangePwdRequest.class);
                if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getTradeNo())) {
                    Date date = new Date();
                    PCLOrder deviceOrder = PCLOrderService.self(date).getByTradeNo(apiReq.getBody().getTradeNo());
                    if (deviceOrder != null) {
                        OperateInfo operateInfo = new OperateInfo(MicroConstants.PROGRAM_TYPE, MicroConstants.PROGRAM_TYPE_NAME);
                        operateInfo.setOperatorType(EOperatorType.Member.index());
                        operateInfo.setOperatorTypeName(EOperatorType.Member.note());
                        operateInfo.setOperator(loginMember.getFullName());
                        operateInfo.setOperateNote("会员切换密码");

                        //切换密码
                        String pwd = PCLOrderService.self(date).changePwd(deviceOrder, operateInfo);
                        if(StringTools.isNotBlank(pwd)) {
                            apiResp.setCode(ClientAPICodeConstants.SUCCESS,null);
                            apiResp.getBody().setPwdStr(pwd);
                        }
                    } else {
                        apiResp.setCode(ClientAPICodeConstants.NULL_DATA, "未找到订单信息");
                    }
                }
            }
        } catch (Exception e) {
            log.error("切换密码失败，" + e.getMessage(), e);
        }
        return apiResp;
    }
}
